今天我們要完成的部分,是我們的product相關頁面以及user相關頁面。
我們先來完成product相關頁面
我們先來修改我們的libs\iron-components\src\lib\ProductCard\ProductCard.tsx
:
import { Box, Card, Text } from "@radix-ui/themes";
import React from "react";
interface ProductCardProps {
title?: string;
description?: string;
price?: string;
imageUrl?: string;
width?: string;
}
const ProductCard: React.FC<ProductCardProps> = (props) => {
const {title, description, price, imageUrl, width = 'auto'} = props;
return (
<Card className={`w:${width}`}>
<Box>
<picture>
<img src={imageUrl} aria-hidden alt="Sample Image" width="100%" />
</picture>
<Text as="div" size="2" weight="bold">
{title}
</Text>
{
price && (
<Text as="div" size="2" color="gray">
{price}
</Text>
)
}
{
description && (
<Text as="div" size="2" color="gray">
{description}
</Text>
)
}
</Box>
</Card>
);
};
export default ProductCard;
通過修改卡片後,該卡片可以顯示產品的圖片、標題、價格和描述。接著修改我們的page,我們要創建了一個包含多個產品卡片的產品展示頁面。
打開apps\iron-ecommerce-next\app\products\products.client.tsx
:
"use client";
import { Flex } from "@radix-ui/themes";
import ProductCard from "libs/iron-components/src/lib/ProductCard";
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface ProductsProps {}
// eslint-disable-next-line no-empty-pattern
const ProductsClient = ({}: ProductsProps) => {
const sampleData = {
title: "Sample Product",
price: "$100.00",
description: "This is a description for the sample product.",
imageUrl: "https://www.w3schools.com/tags/img_girl.jpg"
};
return (
<Flex align="center" justify="center">
<section className="w:60% p:1rem flex flex:wrap flex-direction:row gap:1rem jc:center">
{Array.from({ length: 30 }).map((_, i) => (
<ProductCard
key={i}
title={sampleData.title + ` ${i+1}`}
price={sampleData.price}
description={sampleData.description}
width="30%"
imageUrl={sampleData.imageUrl}
/>
))}
</section>
</Flex>
);
};
export default ProductsClient;
接著,修正單一產品page,打開apps\iron-ecommerce-next\app\products\[id]\productId.client.tsx
:
"use client";
import { Box, Button, Flex, Heading, Text } from "@radix-ui/themes";
import ProductCard from "libs/iron-components/src/lib/ProductCard";
interface ProductIdProps {
productId?: string;
}
// eslint-disable-next-line no-empty-pattern
const ProductIdClient = ({ productId }: ProductIdProps) => {
const sampleData = {
title: "Sample Product",
price: "$100.00",
description: "This is a description for the sample product.",
imageUrl: "https://www.w3schools.com/tags/img_girl.jpg"
};
return (
<Flex align="center" justify="center">
<section className="w:60% p:1rem flex flex:wrap gap:1 jc:center">
<ProductCard
title={sampleData.title}
width="40%"
imageUrl={sampleData.imageUrl}
/>
<Box className="w:40% p:1rem flex flex-direction:column jc:space-between">
<Box>
<Heading as="h1" size="8">
{sampleData.title}
</Heading>
<Text as="p" size="2">
{sampleData.description}
</Text>
</Box>
<Box className="p:1rem">
<Heading as="h1" size="8">
{sampleData.price}
</Heading>
<Button className="w:100% p:1rem">Add to Cart</Button>
</Box>
</Box>
</section>
</Flex>
);
};
export default ProductIdClient;
接著完成user page相關的頁面。
我們先修改用戶頁面,我們設計一個展示user profile的頁面,該頁面包含用戶的頭像、名稱、電子郵件和自我介紹。
打開apps\iron-ecommerce-next\app\user\[id]\userId.client.tsx
並修改:
"use client";
import { Avatar, Box, Card, Flex, Heading, Text } from "@radix-ui/themes";
interface UserIdProps {
userId?: string;
}
// eslint-disable-next-line no-empty-pattern
const UserIdClient = ({ userId }: UserIdProps) => {
const userData = {
name: "John Doe",
email: "john.doe@example.com",
avatar: "https://via.placeholder.com/150",
bio: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque sed suscipit lorem."
};
return (
<Flex align="center" justify="center">
<section className="flex flex:wrap flex-direction:row flex-basis:xs flex-basis:full@<xs gap:1rem jc:center">
<Card mt="2">
<Box className="w:100% m:1rem">
<Flex align="center">
<Avatar
src="https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=64&h=64&dpr=2&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop"
fallback="S"
className="pr:1rem"
/>
<Box>
<Heading as="h1" size="7">{userData.name}</Heading>
<Text as="p" size="1" color="gray">{userData.email}</Text>
</Box>
</Flex>
<Text as="p" size="4">{userData.bio}</Text>
</Box>
</Card>
</section>
</Flex>
);
};
export default UserIdClient;
最後,我們修改個用戶認證頁面,該頁面允許用戶輸入他們的電子郵件和密碼進行登錄。
打開apps\iron-ecommerce-next\app\user\auth\userAuth.client.tsx
:
"use client";
import { Box, Button, Card, Flex, Text, TextField } from "@radix-ui/themes";
import { FormEventHandler } from "react";
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface UserAuthProps {}
// eslint-disable-next-line no-empty-pattern
const UserAuthClient = ({}: UserAuthProps) => {
const handleSubmit: FormEventHandler = (event) => {
event.preventDefault();
console.log('Form submitted');
};
return (
<Flex align="center" justify="center">
<section className="flex flex:wrap flex-direction:row flex-basis:xs flex-basis:full@<xs gap:1rem jc:center">
<Box className="w:100% mt:1rem">
<Card>
<h1 className="text:2xl font:bold text:center mb:4">Login</h1>
<form onSubmit={handleSubmit} className="flex flex-direction:column gap:2">
<div className="flex flex-direction:column gap:1rem">
<TextField.Root >
<TextField.Slot>
<Text as="label">Email</Text>
</TextField.Slot>
<TextField.Input />
</TextField.Root>
<TextField.Root >
<TextField.Slot>
<Text as="label">Password</Text>
</TextField.Slot>
<TextField.Input />
</TextField.Root>
<Button type="submit">Login</Button>
</div>
</form>
</Card>
</Box>
</section>
</Flex>
);
};
export default UserAuthClient;
在這篇文章中,我們將所有頁面基本的顯示都完成實現,簡易的展示了介面。但目前由於沒有狀態,明天會繼續完善網路商店的基本功能。